package com.njxzc.igo.Dao;

import java.util.List;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder.In;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;

import com.njxzc.igo.model.Address;
import com.njxzc.igo.model.Order;
import com.njxzc.igo.model.OrderDetails;
import com.njxzc.igo.model.OrderType;
import com.njxzc.igo.model.Products;
import com.njxzc.igo.model.SelectedItem;
import com.njxzc.igo.utils.HibernateUtils;
import com.njxzc.igo.utils.Pager;

public class OrderDaoImpl implements OrderDao {

	public OrderType findOrderTypeById(int id) {
		Session session = null;
		Transaction tx = null;
		OrderType  ot  = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();
			ot = (OrderType) session.get(OrderType.class, id);
			tx.commit();
		} catch (Exception e) {
			if(tx!=null){
				tx.rollback();
			}
		}finally {
		}
		
		return ot;
	}

	@Override
	public boolean saveOrderByElements(Order o, OrderDetails od, List<SelectedItem> list) {
		Session session = null;
		Transaction tx = null;
		boolean flag = false;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();
			session.save(od);
			session.save(o);
			session.flush();
			for(SelectedItem si :list){
				si.setOrderdetails(od);
				session.save(si);
			}
			tx.commit();
			flag = true;
		} catch (Exception e) {
			if(tx!=null){
				tx.rollback();
			}
			
			//return false;
		}finally {
			HibernateUtils.closeSession();
		}
		return flag;		
		
	}

	@Override
	public List<Order> findOrdersById(long userId) {
		Session session = null;
		Transaction tx = null;
		List<Order> orderlist = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();
			orderlist = session.createQuery("from Order as order where order.user.userId=?").setLong(0, userId).list();
			tx.commit();
		} catch (Exception e) {
			if(tx!=null){
				tx.rollback();
			}
			
		}finally {
		}
		return orderlist;
	}

	public Order findOrderByid(String orderId) {
		Session session = null;
		Transaction tx = null;
		Order order = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();
			order = (Order) session.get(Order.class, orderId);
			tx.commit();
		} catch (Exception e) {
			if(tx!=null){
				tx.rollback();
			}
		}
			
		return order;
	}

	public Order loadOrderSelectedDetails(Order order) {
		ProductDao pd = new ProductDaoImpl();
		AddressDao ad = new AddressDaoImpl();
		OrderDetails od =order.getOrderdetail();
		Address add = ad.findById(Integer.parseInt(od.getAddress()));
		System.out.println(add);
		od.setAdddetails(add);
		
		Set<SelectedItem> selects = order.getOrderdetail().getWillpaiedGoods();
		for(SelectedItem item: selects){
			item.setProduct(pd.findProductsById(item.getProductId()));
		}
		order.setOrderdetail(od);
		return order;
	}

	@Override
	public Pager PagingfindAll(int size, int page) {
		Criterion criterion = null;
		Pager pager = findByPaging(page, size, criterion);
		return pager;
		
	}

	private Pager findByPaging(int page, int size, Criterion... criterions) {
		
		Pager pager = null;
		Session session = null;
		Transaction tx= null;
		int allpages = 0;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();
			Criteria critera = session.createCriteria(Order.class);
			if(criterions!=null){
				for(Criterion criterion : criterions){
					if(criterion!=null){
						critera.add(criterion);
					}
				}
			}
			
			critera.setProjection(Projections.rowCount());
			int rowCount = Integer.parseInt(critera.uniqueResult().toString());
			
			critera.setProjection(null);
			critera.setFirstResult((page-1)*size);
			critera.setMaxResults(size);
			List result =critera.list();
			if (rowCount % size == 0) {
				allpages = rowCount / size;
			} else {
				allpages = rowCount / size+ 1;
			}
			pager = new Pager(size, page, rowCount, allpages, result);
			tx.commit();
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		return pager;
	}

	@Override
	public Pager insertIntoPage(Pager pager) {
		Session session = null;
		Transaction tx= null;
		
		try{
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();
			List<Order> list = pager.getResult();
			for(Order order:list){
				OrderDetails od = order.getOrderdetail();
				Set <SelectedItem> itemsselected = od.getWillpaiedGoods();
				for(SelectedItem si : itemsselected){
					long productId = si.getProductId();
					Products p  = (Products) session.load(Products.class, productId);
					si.setProduct(p);
					session.flush();
				}
			}
		}catch(Exception e ){
			e.printStackTrace();
		}

		return pager;
		
	}

	@Override
	public List<OrderType> findAll() {
		Session session = null;
		Transaction tx = null;
		List<OrderType> otlist = null;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();
			otlist = session.createQuery("select new OrderType(orderTypeId,orderTypeName) from OrderType").list();
			tx.commit();
		} catch (Exception e) {
			if(tx!=null){
				tx.rollback();
			}
		}		
		return otlist;
	}
	public static void main(String[] args) {
		OrderDaoImpl odi = new OrderDaoImpl();
		List<OrderType> ot = odi.findAll();
		System.out.println(ot);
	}

	@Override
	public boolean modifyOrderType(Order order, OrderType orderType) {

		Session session = null;
		Transaction tx = null;
		boolean flag = false;
		try {
			session = HibernateUtils.getSession();
			tx = session.beginTransaction();
			session.update(order);
			session.update(orderType);
			order.setOrdertype(orderType);
			tx.commit();
			flag = true;
		} catch (Exception e) {
			if(tx!=null){
				tx.rollback();
			}
		}
		return flag;		
	}
}
